package com.webull.information.center.carwler.common.util.news;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.databind.JsonNode;
import com.webull.framework.util.UtilJson;
import com.webull.information.center.carwler.common.util.jsoup.HttpJsoupClient;

/**
 * 新浪个股新闻资讯列表解析工具
 *
 * @author shimingjun
 * @version 1.0
 * @date 2016年8月26日 下午3:51:37
 * @since JDK 1.8
 */
@Component
public class CNBCNewsListUitl {
    private @Autowired
    HttpJsoupClient htmlPrase;
    protected final Logger logger = LogManager.getLogger(getClass());

    /*
     * 获取CNBC个股资讯首页对象并解析新闻条目列表
     */
    public List<CNBCItem> parseNewsList(String url) {// url="http://data.cnbc.com/quotes/GOOG/tab/3"
        Document doc = htmlPrase.parseDocumentFromUrl(url, true);
        if (doc == null) {
            logger.warn("SinaNewsListUitl parseNewsList parse url:{} ,is null!!", url);
            return null;
        }
        return parseNewsListUS(doc);
    }


    private List<CNBCItem> parseNewsListUS(Document doc) {
        List<CNBCItem> result = new ArrayList<>();


        Elements es = doc.select("script");
		Pattern pattern0 = Pattern.compile("(?i)\\S+\\s*var\\s*symbolInfo\\s*=");
        for_:
        for (int i = 0; es != null && i < es.size(); i++) {
            if (es.get(i).childNodeSize() != 1)
                continue for_;
            // (function (root)
            String script = es.get(i).childNode(0).outerHtml();

			Matcher m0 = pattern0.matcher(script);

			if (m0.find()) {
				script = StringUtils.substring(script, m0.end());
			} else {
				continue for_;
			}
            //var symbolInfo ="
			// if (!StringUtils.stripToEmpty(script)
			// .matches("(?i)[\\n\\\\r\\\\s]*<title.?[\n\\r\\s]*var\\s*symbolInfo\\s*=.*"))
			// {
			// continue for_;
			// }
			String json = script;
            JsonNode jd = UtilJson.readValue(json, JsonNode.class);
            // 内部新闻
            JsonNode internal = jd.at("/assets/internal/rss/channel/item");
            // 合作伙伴
            JsonNode partner = jd.at("/assets/partner/rss/channel/item");

            Consumer<JsonNode> cumerItem = j0 ->
                    Optional.ofNullable(j0)
                            .filter(v -> !v.isMissingNode() && v.isArray())
                            .ifPresent(v ->
                            {   //最多取最近20条
                                for (int j = 0; j < 20 && j < v.size(); j++) {
                                    JsonNode v0 = v.get(j);
                                    CNBCItem item = new CNBCItem();
                                    item.setMainPic(v0.at("/metadata:image/metadata:url").asText(null));
                                    item.setTitle(v0.at("/title").asText(null));
                                    item.setLink(v0.at("/link").asText(null));
                                    item.setSource(v0.at("/metadata:source").asText("CNBC.com"));
                                    item.setSummery(v0.at("/description").asText(null));
                                    try { //  "pubDate":"Sat, 20 May 2017 17:18:21 GMT",
                                        item.setNewsTime(DateUtils.parseDate(v0.at("/pubDate").asText(null), Locale.ENGLISH, "EEE, dd MMM yyyy HH:mm:ss Z"));//
                                    } catch (Exception e) {
                                        logger.error(e);
                                    }

                                    if (StringUtils.isBlank(item.getLink()) || StringUtils.isBlank(item.getTitle()) || StringUtils.isBlank(item.getSource()) || item.getNewsTime() == null)
                                        return;
                                    result.add(item);
                                }
                            });

            cumerItem.accept(internal);
            cumerItem.accept(partner);
            break for_;
        }
        return result;
    }

    public static void main(String[] args) throws IOException {

		// String cript = "<title itemprop=\"name\">AAPL:NASDAQ: Apple Inc Stock Quote
		// and News - CNBC</title>\n"
		// + " <script type=\"text/javascript\">\n"
		// + " var chartWorksInfo = {\"token\":\"NWlcnoBARaWwTJnT9gNbWteC2AeA\",
		// \"altSymbolName\":\"AAPL.O\"};\n"
		// + " var tickerinfo = \"\";\n"
		// + " tickerinfo = \"US|NASDAQ|STOCK|Common Stock\";\n"
		// + " var symbolInfo = {\"change_pct\":\"1";
		// Pattern pattern0 = Pattern.compile("(?i)\\S+\\s*var\\s*symbolInfo\\s*=");
		// Matcher m0 = pattern0.matcher(cript);
		// System.out.println(m0.find());
		//
		// if (1 == 1)
		// return;
		String url2 = "http://www.cnbc.com/quotes/?symbol=AAPL&tab=news";
//		url2 = "http://data.cnbc.com/quotes/SORT/tab/3";
        // Connection connection = Jsoup.connect(url2)
        // Connection connection = Jsoup.connect(urlHK)
        Connection connection = Jsoup.connect(url2).userAgent(
                "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36")
                // .header("x-client-data",
                // "CIq2yQEIpbbJAQjEtskBCP2VygEIwpjKAQjwnMoB")
                .header("x-client-data", RandomStringUtils.randomAlphanumeric(40));
        connection.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 1080)));
        Document doc = connection.timeout(10000).get();

        // List<CNBCItem> items = new SinaNewsListUitl().parseNewsListHK(doc);
        List<CNBCItem> items = new CNBCNewsListUitl().parseNewsListUS(doc);
        System.out.println(items);
    }

    public static class CNBCItem {
        private Date newsTime;
        private String mainPic;
        private String title;
        private String link;
        private String source;
        private String summery;

        public Date getNewsTime() {
            return newsTime;
        }

        public void setNewsTime(Date newsTime) {
            this.newsTime = newsTime;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public String getLink() {
            return link;
        }

        public void setLink(String link) {
            this.link = link;
        }

        public String getSource() {
            return source;
        }

        public void setSource(String source) {
            this.source = source;
        }

        public String getMainPic() {
            return mainPic;
        }

        public void setMainPic(String mainPic) {
            this.mainPic = mainPic;
        }

        public String getSummery() {
            return summery;
        }

        public void setSummery(String summery) {
            this.summery = summery;
        }

        @Override
        public String toString() {
            return "CNBCItem [newsTime=" + newsTime + ", source=" + source + ", title=" + title + ", link=" + link
                    + "]";
        }

    }

}
